﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Data;
using System.IO;
using System.Windows.Media.Animation;
using System.Diagnostics;

namespace PagedDataGridControls
{
    /// <summary>
    /// Interaction logic for PagedDataGrid.xaml
    /// </summary>
    public partial class PagedDataGrid : UserControl
    {
        RoutedUICommand nextCmd = new RoutedUICommand();
        RoutedUICommand previousCmd = new RoutedUICommand();
        RoutedUICommand lastCmd = new RoutedUICommand();
        RoutedUICommand firstCmd = new RoutedUICommand();


        public static readonly RoutedEvent RaiseExceptionNotifyEvent = EventManager.RegisterRoutedEvent("RaiseExceptionNotifyEvent",
    RoutingStrategy.Tunnel, typeof(RoutedEventHandler), typeof(PagedDataGrid));

        public event RoutedEventHandler RaiseExceptionNotify
        {
            add { AddHandler(RaiseExceptionNotifyEvent, value); }
            remove { RemoveHandler(RaiseExceptionNotifyEvent, value); }
        }

        /// <summary>
        /// Set or Get the DetailView Visiblity
        /// If true ,when use navigate the datarow, the detail view will show detail data
        /// </summary>
        public bool IsShowDetailView
        {
            get
            {
                if (hostPanel.Visibility == System.Windows.Visibility.Visible)
                {
                    return true;
                }
                else
                {
                    return false;
                }
            }
            set
            {
                if (value)
                {
                    hostPanel.Visibility = System.Windows.Visibility.Visible;
                    
                }
                else
                {
                    hostPanel.Visibility = System.Windows.Visibility.Collapsed;
                }
                }
        }

        /// <summary>
        /// Current Page Index
        /// Start from 1
        /// </summary>
        private int CurrentPosition { get; set; }

        /// <summary>
        /// 所有页数
        /// </summary>
        private int AllPosition { get; set; }

        /// <summary>
        /// 所有记录总数
        /// </summary>
        public int AllRowCount
        {
            get { return (int)GetValue(AllRowCountProperty); }
            set { SetValue(AllRowCountProperty, value); }
        }
        public static readonly DependencyProperty AllRowCountProperty =
            DependencyProperty.Register("AllRowCount", typeof(int), typeof(PagedDataGrid),
            new UIPropertyMetadata(null));

        /// <summary>
        /// Default value is 1000
        /// </summary>
        public int DataCountPerPage
        {
            get { return (int)GetValue(DataCountPerPageProperty); }
            set { SetValue(DataCountPerPageProperty, value); }
        }
        public static readonly DependencyProperty DataCountPerPageProperty =
            DependencyProperty.Register("DataCountPerPage", typeof(int), typeof(PagedDataGrid),
            new UIPropertyMetadata(1000));

        /// <summary>
        /// 本控件内保证的数据
        /// </summary>
        private DataTable MyDataContext { get; set; }

        /// <summary>
        /// 
        /// </summary>
        private DataTable MyTempContext
        {
            get
            {
                return MyDataContext.Clone();;
            }
        }


        /// <summary>
        /// 输入的数据
        /// </summary>
        public object MyDataSource
        {
            set
            {
                try
                {
                    MyDataContext = (DataTable)value;

                    #region Calc AllPosition
                    AllRowCount = MyDataContext.Rows.Count;

                    AllPosition = AllRowCount / DataCountPerPage;
                    
                    Debug.WriteLine("Set All position" + AllPosition);
                    if (AllPosition == 0)
                    {
                        AllPosition = 1;
                    }
                    else
                    {
                        //如果有多出来的一个，则多加一页
                        if (MyDataContext.Rows.Count % DataCountPerPage > 1)
                        {
                            AllPosition++;
                        }
                    }

                    txtPageCount.Text = AllPosition.ToString();
                    #endregion

                    #region Automatic navigate to first page
                    //当有数据的时候才去获取第一页
                    if (AllRowCount > 0)
                    {
                        CurrentPosition = 1;
                        comboGoTo.SelectedIndex = 0;
                        //RefreshPage();
                    }
                    //txtCurrentPageIndex.Text = CurrentPosition.ToString();
                    #endregion

                    #region Fill with go to page combobox list
                    comboGoTo.Items.Clear();
                    for (int i = 1; i <= AllPosition; i++)
                    {
                        ComboBoxItem item = new ComboBoxItem();
                        item.Content = i;
                        comboGoTo.Items.Add(item);
                    }
                    #endregion
                }
                catch (Exception ee)
                {
                   
                    NotifyExternalWithException(ee);
                }
            }
            get
            {
                return MyDataContext;
            }
        }

        private void NotifyExternalWithException(Exception ee)
        {
            Debug.WriteLine(ee.Message);
            RaiseEvent(new MyEventRoutedArgs(RaiseExceptionNotifyEvent) { CurrentException=ee});
            
        }

        public void ResetMyDataSource()
        {
            dataGrid = null;
            
        }



        public PagedDataGrid()
        {
            InitializeComponent();

            this.CommandBindings.Add(new CommandBinding(nextCmd, nextCmd_Executed, nextCmd_CanExecuted));
            this.CommandBindings.Add(new CommandBinding(previousCmd, previousCmd_Executed, previousCmd_CanExecuted));
            this.CommandBindings.Add(new CommandBinding(lastCmd, lastCmd_Executed, lastCmd_CanExecuted));
            this.CommandBindings.Add(new CommandBinding(firstCmd, firstCmd_Executed, firstCmd_CanExecuted));

            butFirst.Command = firstCmd;
            butNext.Command = nextCmd;
            butLast.Command = lastCmd;
            butPrevious.Command = previousCmd;

            //for animation
            this.RegisterName("hostPanel", hostPanel);

           // this.IsShowDetailView = false;  
        }

        void firstCmd_Executed(object sender, ExecutedRoutedEventArgs e)
        {
            CurrentPosition =1 ;
            RefreshPage();
        }

        private void RefreshPage()
        {
            try
            {
                DataTable dt = MyTempContext.Clone();
                //显示当前页码
                //txtCurrentPageIndex.Text = CurrentPosition.ToString();

                for (int i = (CurrentPosition - 1) * DataCountPerPage; i < CurrentPosition * DataCountPerPage; i++)
                {
                    //当最后一页时可能只有一条或几条数据，而未满一页。
                    //此时需要只获取几条内容即可
                    if (i == AllRowCount)
                    {
                        break;
                    }
                    DataRow row = dt.NewRow();

                    row.ItemArray = MyDataContext.Rows[i].ItemArray;

                    dt.Rows.Add(row);
                }

                dataGrid.DataContext = null;
                dataGrid.DataContext = dt;
            }
            catch (Exception ee)
            {
                NotifyExternalWithException(ee);
            }
        }

        void firstCmd_CanExecuted(object sender, CanExecuteRoutedEventArgs e)
        {
            if (MyDataContext == null)
            {
                e.CanExecute = false;
            }
            else
            {
                if (CurrentPosition > 1)
                {
                    e.CanExecute = true;
                }
                else
                {
                    e.CanExecute = false;
                }
            }
        }

        void lastCmd_Executed(object sender, ExecutedRoutedEventArgs e)
        {
            CurrentPosition = AllPosition;
            RefreshPage();
        }

        void lastCmd_CanExecuted(object sender, CanExecuteRoutedEventArgs e)
        {
 
            if (MyDataContext == null)
            {
                e.CanExecute = false;
            }
            else
            {
                if (CurrentPosition-1 <= AllPosition)
                {
                    e.CanExecute = false;
                }
                else
                {
                    e.CanExecute = true;
                }
            }
        }

        void nextCmd_Executed(object sender, ExecutedRoutedEventArgs e)
        {
            CurrentPosition++;
            RefreshPage();
        }

        void nextCmd_CanExecuted(object sender, CanExecuteRoutedEventArgs e)
        {
            if (MyDataContext == null)
            {
                e.CanExecute = false;
            }
            else
            {
                if (CurrentPosition-1 <= AllPosition)
                {
                    e.CanExecute = false;
                }
                else
                {
                    e.CanExecute = true;
                }
            }
        }

        void previousCmd_Executed(object sender, ExecutedRoutedEventArgs e)
        {
            CurrentPosition--;
            RefreshPage();
        }

        void previousCmd_CanExecuted(object sender, CanExecuteRoutedEventArgs e)
        {
            if (MyDataContext == null)
            {
                e.CanExecute = false;
            }
            else
            {
                if (CurrentPosition >1)
                {
                    e.CanExecute = true;
                }
                else
                {
                    e.CanExecute = false;
                }
            }
        }

        private void comboGoTo_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            try
            {
                if (e.AddedItems.Count > 0)
                {
                    ComboBoxItem item = e.AddedItems[0] as ComboBoxItem;
                    CurrentPosition = int.Parse(item.Content.ToString());
                    RefreshPage();
                }
            }
            catch (Exception ee)
            {
                NotifyExternalWithException(ee);
            }
        }

        private void dataGrid_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            if (e.AddedItems.Count > 0)
            {
                try
                {

                    IList<DataGridCellInfo> info = dataGrid.SelectedCells;
                    List<string> headerList = new List<string>();
                    foreach (var header in info)
                    {
                        headerList.Add(header.Column.Header.ToString());
                    }
                    DataRowView view = e.AddedItems[0] as DataRowView;

                    hostPanel.SetMyData(headerList, view);

                    
                }
                catch (Exception ee)
                {
                    NotifyExternalWithException(ee);
                }
            }
        }


    }
}
